package com.ruoyi.system.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.plugin.table.HackLoopTableRenderPolicy;
import com.google.common.collect.Lists;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.UserEducationVo;
import com.ruoyi.system.mapper.MeetingUserSignatureMapper;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.IDeptFileArchivedService;
import com.ruoyi.system.service.IMeetingSummaryService;
import com.ruoyi.system.service.ISysUserService;
import liquibase.pro.packaged.A;
import liquibase.pro.packaged.O;
import liquibase.pro.packaged.S;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.MeetingManagementMapper;
import com.ruoyi.system.service.IMeetingManagementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;

/**
 * 会议管理Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-02
 */
@Service
@Slf4j
public class MeetingManagementServiceImpl implements IMeetingManagementService
{
    @Autowired
    private MeetingManagementMapper meetingManagementMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private MeetingUserSignatureMapper meetingUserSignatureMapper;
    @Autowired
    private SysPostMapper sysPostMapper;
    @Autowired
    private IMeetingSummaryService meetingSummaryService;
    @Autowired
    private IDeptFileArchivedService deptFileArchivedService;


    /**
     * 查询会议管理
     *
     * @param id 会议管理主键
     * @return 会议管理
     */
    @Override
    public MeetingManagement selectMeetingManagementById(Long id)
    {
        MeetingManagement meetingManagement = meetingManagementMapper.selectMeetingManagementById(id);
        //处理参会人员
        String meetingAttendeeType = meetingManagement.getMeetingAttendeeType();
        if("1".equals(meetingAttendeeType)){
            String meetingAttendee = meetingManagement.getMeetingAttendee();
            if(StringUtils.isNotBlank(meetingAttendee)){
                List<String> userIdList = Arrays.asList(meetingAttendee.split(","));
                ArrayList<SysUser> userList = new ArrayList();
                for(String userId : userIdList){
                    SysUser user = sysUserService.selectUserById(Long.valueOf(userId));
                    userList.add(user);
                }
                meetingManagement.setUserIdList(userIdList);
                meetingManagement.setUserList(userList);
            }
        }
        //处理会议材料
        String meetingMaterial = meetingManagement.getMeetingMaterial();
        if(StringUtils.isNotBlank(meetingMaterial)){
            List<String> meetingMateriaList = Arrays.asList(meetingMaterial.split(","));
            meetingManagement.setMeetingMaterialList(meetingMateriaList);
        }
        return meetingManagement;
    }

    /**
     * 查询会议管理列表
     *
     * @param meetingManagement 会议管理
     * @return 会议管理
     */
    @Override
    public List<MeetingManagement> selectMeetingManagementList(MeetingManagement meetingManagement)
    {
        List<MeetingManagement> meetingManagementList = meetingManagementMapper.selectMeetingManagementList(meetingManagement);
        for(MeetingManagement meeting : meetingManagementList){
            //处理参会人员
            String meetingAttendeeType = meeting.getMeetingAttendeeType();
            if("1".equals(meetingAttendeeType)){
                String meetingAttendee = meeting.getMeetingAttendee();
                if(StringUtils.isNotBlank(meetingAttendee)){
                    List<String> userIdList = Arrays.asList(meetingAttendee.split(","));
                    ArrayList<SysUser> userList = new ArrayList();
                    for(String userId : userIdList){
                        SysUser user = sysUserService.selectUserById(Long.valueOf(userId));
                        userList.add(user);
                    }
                    meeting.setUserIdList(userIdList);
                    meeting.setUserList(userList);
                }
            }

            //处理会议材料
            String meetingMaterial = meetingManagement.getMeetingMaterial();
            if(StringUtils.isNotBlank(meetingMaterial)){
                List<String> meetingMateriaList = Arrays.asList(meetingMaterial.split(","));
                meetingManagement.setMeetingMaterialList(meetingMateriaList);
            }
            String createBy = meeting.getCreateBy();
            SysUser user = sysUserService.selectUserById(Long.valueOf(createBy));
            meeting.setCreateBy(user.getNickName());
        }
        return meetingManagementList;
    }

    /**
     * 新增会议管理
     *
     * @param meetingManagement 会议管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertMeetingManagement(MeetingManagement meetingManagement)
    {
        meetingManagement.setCreateTime(DateUtils.getNowDate());
        //参会人员
        List<String> userIdList = meetingManagement.getUserIdList();
        String meetingAttendee = StringUtils.join(userIdList, ",");
        meetingManagement.setMeetingAttendee(meetingAttendee);
        //会议材料
        List<String> meetingMaterialList = meetingManagement.getMeetingMaterialList();
        String meetingMaterial = StringUtils.join(meetingMaterialList, ",");
        meetingManagement.setMeetingMaterial(meetingMaterial);

        meetingManagementMapper.insertMeetingManagement(meetingManagement);

        //如果参会人员是本部门人员或者全体人员
        if(CollectionUtils.isEmpty(userIdList)){
            String meetingAttendeeType = meetingManagement.getMeetingAttendeeType();
            if("0".equals(meetingAttendeeType)){
                //本部门人员
                SysUser user = new SysUser();
                user.setDeptId(meetingManagement.getDeptId());
                List<SysUser> sysUsers = sysUserService.selectUserList(user);
                userIdList = sysUsers.stream().map(o -> o.getUserId().toString()).collect(Collectors.toList());
            }else if("2".equals(meetingAttendeeType)){
                //全体人员
                SysUser user = new SysUser();
                List<SysUser> sysUsers = sysUserService.selectUserList(user);
                userIdList = sysUsers.stream().map(o -> o.getUserId().toString()).collect(Collectors.toList());
            }
        }
        //补录会议手动添加签到信息
        String clearingMeeting = meetingManagement.getClearingMeeting();
        String meetingSignature = meetingManagement.getMeetingSignature();
        //是否补录会议（0:不是1：是）并且 会议签到（0:不签到 1:定位签到）
        if("0".equals(clearingMeeting)&&"1".equals(meetingSignature)){
            //添加会议签到人员信息
            for(String userId : userIdList){
                MeetingUserSignature meetingUserSignature = new MeetingUserSignature();
                SysUser user = sysUserService.selectUserById(Long.valueOf(userId));
                meetingUserSignature.setMeetingId(meetingManagement.getId());
                meetingUserSignature.setUserId(Long.valueOf(userId));
                meetingUserSignature.setUserName(user.getNickName());
                meetingUserSignature.setPhonenumber(user.getPhonenumber());
                meetingUserSignature.setUserDeptName(user.getDept().getDeptName());
                meetingUserSignature.setUserPartyType(user.getPartyType());
                List<Long> postIds = sysPostMapper.selectPostListByUserId(Long.valueOf(userId));
                String postId = StringUtils.join(postIds, ",");
                meetingUserSignature.setUserPostId(postId);
                meetingUserSignature.setCreateTime(DateUtils.getNowDate());
                meetingUserSignature.setCreateBy(meetingManagement.getCreateBy());
                meetingUserSignature.setMeetingType(meetingManagement.getMeetingType());
                meetingUserSignatureMapper.insertMeetingUserSignature(meetingUserSignature);
            }

        }
        //创建会议归纳文件夹
        DeptFileArchived deptFileArchived = new DeptFileArchived();
        deptFileArchived.setParentId(1L);
        deptFileArchived.setDeptId(meetingManagement.getDeptId());
        deptFileArchived.setFileName(meetingManagement.getMeetingTheme());
        deptFileArchived.setFileType("0");
        deptFileArchived.setCreateBy(meetingManagement.getCreateBy());
        deptFileArchived.setAssociationId(String.valueOf(meetingManagement.getId()));
        SysUser user = sysUserService.selectUserById(Long.valueOf(meetingManagement.getCreateBy()));
        deptFileArchived.setCreateName(user.getNickName());
        deptFileArchivedService.insertDeptFileArchived(deptFileArchived);
        return AjaxResult.success("添加成功");
    }

    /**
     * 修改会议管理
     *
     * @param meetingManagement 会议管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMeetingManagement(MeetingManagement meetingManagement)
    {
        meetingManagement.setUpdateTime(DateUtils.getNowDate());
        //会议结束直接发起会议纪要
        String status = meetingManagement.getStatus();
        if("2".equals(status)){
            MeetingManagement meetingManagementVo = meetingManagementMapper.selectMeetingManagementById(meetingManagement.getId());
            MeetingSummary meetingSummary = new MeetingSummary();
            meetingSummary.setMeetingId(meetingManagement.getId());
            String meetingEndTime = meetingManagementVo.getMeetingEndTime();
            DateTime meetingEndTimeDate = DateUtil.parse(meetingEndTime, "yyyy-MM-dd HH:mm:ss");
            //截至时间是会决结束日期3天之后
            Date dateTime = DateUtil.offsetDay(meetingEndTimeDate, 3);
            meetingSummary.setEndTime(dateTime);
            meetingSummaryService.insertMeetingSummary(meetingSummary);
        }
        return meetingManagementMapper.updateMeetingManagement(meetingManagement);
    }


    /**
     * 删除会议管理信息
     *
     * @param id 会议管理主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMeetingManagementById(Long id)
    {
        int i = meetingManagementMapper.deleteMeetingManagementById(id);
        meetingUserSignatureMapper.deleteMeetingUserSignatureByMeetingId(id);
        return i;
    }

    /**
     * 查询会议会议签到统计列表
     *
     * @param meetingManagement 会议管理
     * @return 会议管理集合
     */
    @Override
    public List<MeetingManagement> selectMeetingSignaturelist(MeetingManagement meetingManagement){
        List<MeetingManagement> meetingManagementList = meetingManagementMapper.selectMeetingManagementList(meetingManagement);
        for(MeetingManagement meeting : meetingManagementList){
            Long id = meeting.getId();
            MeetingUserSignature meetingUserSignature = new MeetingUserSignature();
            meetingUserSignature.setMeetingId(id);
            List<MeetingUserSignature> meetingUserSignatureList = meetingUserSignatureMapper.selectMeetingUserSignatureList(meetingUserSignature);
            //正常签到、迟到、补签
            long count = meetingUserSignatureList.stream().filter(o -> o.getStatus().equals("1") || o.getStatus().equals("4")|| o.getStatus().equals("3")).count();
            meeting.setSignatureCount((int) count);
            meeting.setMeetingAttendeeCount(meetingUserSignatureList.size());
        }
        return meetingManagementList;
    }

    /**
     * 查询参加的会议列表
     *
     * @param meetingManagement 会议管理
     * @return 会议管理集合
     */
    @Override
    public List<MeetingManagement> selectJoinMeetingManagementList(MeetingManagement meetingManagement){
        List<MeetingManagement> resultList = new ArrayList();
        List<MeetingManagement> meetingManagementList = meetingManagementMapper.selectMeetingManagementList(meetingManagement);
        for(MeetingManagement meeting : meetingManagementList){
            //处理参会人员
            String meetingAttendeeType = meeting.getMeetingAttendeeType();
            if("1".equals(meetingAttendeeType)){
                String meetingAttendee = meeting.getMeetingAttendee();
                if(StringUtils.isNotBlank(meetingAttendee)){
                    List<String> userIdList = Arrays.asList(meetingAttendee.split(","));
                    ArrayList<SysUser> userList = new ArrayList();
                    for(String userId : userIdList){
                        SysUser user = sysUserService.selectUserById(Long.valueOf(userId));
                        userList.add(user);
                    }
                    meeting.setUserIdList(userIdList);
                    meeting.setUserList(userList);
                    if(userIdList.contains(meetingManagement.getUserId())){
                        resultList.add(meeting);
                    }
                }
            }else if("0".equals(meetingAttendeeType)){
                //当前登陆人
                SysUser user1 = sysUserService.selectUserById(Long.valueOf(meetingManagement.getUserId()));
                String createBy = meeting.getCreateBy();
                SysUser user2 = sysUserService.selectUserById(Long.valueOf(createBy));
                if(user1.getDeptId().equals(user2.getDeptId())){
                    resultList.add(meeting);
                }

            }else if("2".equals(meetingAttendeeType)){
                resultList.add(meeting);
            }
        }
        return resultList;
    }


    /**
     * 查询已参加的会议列表
     *
     * @param meetingManagement 会议管理
     * @return 会议管理集合
     */
    @Override
    public List<MeetingManagement> selectjoinedlist(MeetingManagement meetingManagement){
        List<MeetingManagement> resultList = new ArrayList();
        List<MeetingManagement> meetingManagementList = meetingManagementMapper.selectJoinedMeetingManagementList(meetingManagement);
        for(MeetingManagement meeting : meetingManagementList){
            MeetingUserSignature meetingUserSignature = new MeetingUserSignature();
            meetingUserSignature.setUserId(Long.valueOf(meetingManagement.getUserId()));
            meetingUserSignature.setMeetingId(Long.valueOf(meeting.getId()));
            MeetingUserSignature userSignature = meetingUserSignatureMapper.selectMeetingUserSignature(meetingUserSignature);
            //排除没有签到和请假的会议
            if(!ObjectUtils.isEmpty(userSignature)){
                String status = userSignature.getStatus();
                if(status.equals("0")||status.equals("2")){
                    continue;
                }
            }
            //处理参会人员
            String meetingAttendeeType = meeting.getMeetingAttendeeType();
            if("1".equals(meetingAttendeeType)){
                String meetingAttendee = meeting.getMeetingAttendee();
                if(StringUtils.isNotBlank(meetingAttendee)){
                    List<String> userIdList = Arrays.asList(meetingAttendee.split(","));
                    ArrayList<SysUser> userList = new ArrayList();
                    for(String userId : userIdList){
                        SysUser user = sysUserService.selectUserById(Long.valueOf(userId));
                        userList.add(user);
                    }
                    meeting.setUserIdList(userIdList);
                    meeting.setUserList(userList);
                    if(userIdList.contains(meetingManagement.getUserId())){
                        resultList.add(meeting);
                    }
                }
            }else if("0".equals(meetingAttendeeType)){
                //当前登陆人
                SysUser user1 = sysUserService.selectUserById(Long.valueOf(meetingManagement.getUserId()));
                String createBy = meeting.getCreateBy();
                SysUser user2 = sysUserService.selectUserById(Long.valueOf(createBy));
                if(user1.getDeptId().equals(user2.getDeptId())){
                    resultList.add(meeting);
                }

            }else if("2".equals(meetingAttendeeType)){
                resultList.add(meeting);
            }
        }
        return resultList;
    }


    /**
     * 导出会议通知
     */
    @Override
    public void exportMeetingNotify(MeetingManagement meetingManagement, HttpServletResponse response){
        MeetingManagement meeting = meetingManagementMapper.selectMeetingManagementById(meetingManagement.getId());
        String meetingTheme = meeting.getMeetingTheme();
        String associateItem = meeting.getAssociateItem();
        String meetingStartTime = meeting.getMeetingStartTime();
        String year = meetingStartTime.substring(0, 5);
        String month = meetingStartTime.substring(5, 7);
        String day = meetingStartTime.substring(8, 10);
        String meetingEndTime = meeting.getMeetingEndTime();
        String meetingPlace = meeting.getMeetingPlace();
        String compereName = meeting.getCompereName();
        String meetingContent = meeting.getMeetingContent();
        String meetingRequire = meeting.getMeetingRequire();
        String deptName = meeting.getDeptName();
        Date startTime = DateUtil.parse(meetingStartTime, "yyyy-MM-dd");
        Date dateTime = DateUtil.offsetDay(startTime, -7);
        String notifyTime = DateUtil.format(dateTime, "yyyy年MM月dd日");

        try {
            //组装数据
            Map<String, Object> map = new HashMap<>();
            map.put("meetingTheme",meetingTheme);
            map.put("associateItem",associateItem);
            map.put("month",month);
            map.put("day",day);
            map.put("meetingStartTime",meetingStartTime);
            map.put("meetingEndTime",meetingEndTime);
            map.put("meetingPlace",meetingPlace);
            map.put("compereName",compereName);
            map.put("meetingContent",meetingContent);
            map.put("meetingRequire",meetingRequire);
            map.put("deptName",deptName);
            map.put("notifyTime",notifyTime);

            //获取文件名称
            String name = meeting.getMeetingTheme();
            //获取模板
            ClassPathResource classPathResource = new ClassPathResource("static/meetNotify.docx");
            String resource = classPathResource.getURL().getPath();
            ConfigureBuilder builder = Configure.builder();
            builder.useSpringEL();
            XWPFTemplate template = XWPFTemplate.compile(resource,builder.build()).render(map);

            //禁用缓存
            response.setHeader(HttpHeaders.PRAGMA, "No-cache");
            response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache");
            response.setHeader("Content-Disposition", "attachment; filename="+""+"notify.docx");
            response.setHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
            OutputStream outputStream = response.getOutputStream();
            template.write(outputStream);
            outputStream.close();
            template.close();

        }catch(IOException e){
            //异常处理
            log.error("文件导出错误", e);
        }
    }

    /**
     * 导出会议签到
     */
    @Override
    public void exportMeetingSignature(MeetingManagement meetingManagement, HttpServletResponse response){
        MeetingManagement meeting = meetingManagementMapper.selectMeetingManagementById(meetingManagement.getId());
        MeetingUserSignature meetingUserSignature = new MeetingUserSignature();
        meetingUserSignature.setMeetingId(meetingManagement.getId());
        List<MeetingUserSignature> meetingUserSignatureList = meetingUserSignatureMapper.selectMeetingUserSignatureList(meetingUserSignature);
        try {
            //获取数据
            String meetingTheme = meeting.getMeetingTheme();
            String meetingStartTime = meeting.getMeetingStartTime();
            String meetingPlace = meeting.getMeetingPlace();
            String compereName = meeting.getCompereName();
            // TODO 渲染其他类型的数据请参考官方文档
            //组装表格列表数据
            int i =0;
            List<Map<String,Object>> detailList=new ArrayList<Map<String,Object>>();
            for(MeetingUserSignature signature : meetingUserSignatureList){
                Map<String, Object> detailMap = new HashMap<String, Object>();
                String userPostId = signature.getUserPostId();
                if(StringUtils.isNotBlank(userPostId)){
                    List<String> userPostIdList = Arrays.asList(userPostId.split(","));
                    List<String> postNameList = new ArrayList();
                    for(String postId : userPostIdList){
                        SysPost sysPost = sysPostMapper.selectPostById(Long.valueOf(postId));
                        postNameList.add(sysPost.getPostName());
                    }
                    String postNames = String.join(",", postNameList);
                    signature.setPostNames(postNames);
                }
                //序号
                detailMap.put("index", i+1);
                //姓名
                detailMap.put("user_name", signature.getUserName());
                //职务
                detailMap.put("post_name",signature.getPostNames());
                detailList.add(detailMap);
                i++;
            }
            //word模板地址获取方式二：优点---相比上一种方式，这种方法不会在linux或者jar上失效
            ClassPathResource classPathResource = new ClassPathResource("static/meetSignature.docx");
            String resource = classPathResource.getURL().getPath();
            //渲染表格
            HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
            Configure config = Configure.newBuilder().bind("detailList", policy).build();

            XWPFTemplate template = XWPFTemplate.compile(resource, config).render(
                    new HashMap<String, Object>() {{
                        put("detailList", detailList);
                        put("meetingTheme", meetingTheme);
                        put("meetingStartTime", meetingStartTime);
                        put("meetingPlace",meetingPlace);
                        put("compereName",compereName);
                    }}
            );

            //禁用缓存
            response.setHeader(HttpHeaders.PRAGMA, "No-cache");
            response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache");
            response.setHeader("Content-Disposition", "attachment; filename="+""+"signature.docx");
            response.setHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
            OutputStream outputStream = response.getOutputStream();
            template.write(outputStream);
            outputStream.close();
            template.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 党建大数据 会议分布
     */
    @Override
    public List<UserEducationVo>  meetingStructure(String queryYear){
        List<UserEducationVo> userEducationVolist= Lists.newArrayList();
        String startTime = queryYear+"-01-01 00:00:00";
        String endTime = queryYear+"-12-31 23:59:59";
        MeetingManagement meetingManagement = new MeetingManagement();
        meetingManagement.setMeetingStartTime(startTime);
        meetingManagement.setMeetingEndTime(endTime);
        List<MeetingManagement> meetingManagements = meetingManagementMapper.selectMeetingManagementList(meetingManagement);
        Map<String, List<MeetingManagement>> collect = meetingManagements.stream().collect(Collectors.groupingBy(MeetingManagement::getMeetingType));
        for(Map.Entry<String, List<MeetingManagement>> entry : collect.entrySet()){
            String key = entry.getKey();
            List<MeetingManagement> value = entry.getValue();
            UserEducationVo userEducationVo = new UserEducationVo();
            userEducationVo.setName(key);
            userEducationVo.setValue(value.size());
            userEducationVolist.add(userEducationVo);
        }
        return userEducationVolist;
    }
}
